home *** CD-ROM | disk | FTP | other *** search
/ Winzipper / Winzipper_ISO.iso / programming / oracle7 7.2 / DB / UTIL72 / DBMSMAIL.SQL < prev    next >
Encoding:
Text File  |  1995-05-09  |  11.0 KB  |  277 lines

  1. rem 
  2. rem $Header: dbmsmail.sql 7020100.1 94/09/23 22:14:46 cli Generic<base> $ 
  3. rem 
  4. Rem  Copyright (c) 1991 by Oracle Corporation 
  5. Rem    NAME
  6. Rem      dbmsmail.sql - send ora*mail
  7. Rem    DESCRIPTION
  8. Rem
  9. Rem    RETURNS
  10. Rem 
  11. Rem    NOTES
  12. Rem      The procedural option is needed to use this facility.
  13. Rem
  14. Rem      NOTE for Upgrade from versions prior to 7.0.14:
  15. Rem         You will need to create the view 'dbms_mail.v$myclientinfo'
  16. Rem        under schema 'sys' as described in step (3) belo.
  17. Rem
  18. Rem    MODIFIED   (MM/DD/YY)
  19. Rem     rkooi      04/20/93 -  merge changes from branch 1.10.312.1 
  20. Rem     rkooi      04/07/93 -  security improvements 
  21. Rem     rkooi      09/30/92 -  add some comments 
  22. Rem     rkooi      09/02/92 -  change ORU errors 
  23. Rem     rkooi      06/10/92 -  add rae errors 
  24. Rem     rkooi      01/10/92 -  Creation 
  25. rem
  26.  
  27. create or replace package dbms_mail as
  28.  
  29.   -----------
  30.   --  OVERVIEW
  31.   --
  32.   --  This package is an interface to the Oracle*Mail product.  You can 
  33.   --  send an Oracle*Mail message by calling the 'send' procedure.  The mail
  34.   --  will be sent when the transaction is committed.  This procedure
  35.   --  can be called from a trigger.  This package will work with Version 1.1
  36.   --  of Oracle*Mail.
  37.  
  38.   ---------
  39.   --  SETUP
  40.   --
  41.   --  Before creating this package, you must 
  42.   --
  43.   --  1) Run the 'utlmail.sql' script on the mail database (with
  44.   --     Oracle*Mail Version 1.1 installed) as user 'email'. Then create 
  45.   --     a special database account in the mail database,
  46.   --     <mailuser>/<mailpassword>, with connect privilege only:
  47.   --
  48.   --        create user <mailuser> identified by <mailpassword>;
  49.   --        grant connect to <mailuser>;
  50.   --
  51.   --     Then make <mailuser> a valid Oracle*Mail user.
  52.   --
  53.   --  2) Create a database account in the database from which you wish
  54.   --     to send email.  This is so the following database link is not
  55.   --     widely accessible and so that you can control who has access
  56.   --     to this package.  Assume this account is named <localmailacct>.
  57.   --  
  58.   --     Connect to <localmailacct> and create a database link named 
  59.   --     <mailnode> which points to the mail database:
  60.   --
  61.   --        create database link <mailnode> connect to <mailuser> identified by
  62.   --          <mailpassword> using '...';
  63.   --
  64.   --     As mentioned in step (1), <mailuser> must be a valid Oracle*Mail 
  65.   --     user for the mail database AND <mailuser>/<mailpassword> must be 
  66.   --     a valid DATABASE user in the mail database (but should only have 
  67.   --     "connect" permission).
  68.   --
  69.   --     In order for "global naming" to be enabled, the node name must be
  70.   --     the same as the name of the database.  See the DBA Guide for
  71.   --     more information on global naming.  If global naming is
  72.   --     disabled for this database, then the name of the database link 
  73.   --     is not important.
  74.   --
  75.   --  3) In the database from which you wish to send email, create the 
  76.   --     dbms_mail$myclientinfo view:
  77.   --
  78.   --       connect sys/chg_on_install
  79.   --       create or replace view dbms_mail$myclientinfo as
  80.   --         select ' [SENDER=(' ||
  81.   --           substr(osuser || ',' || user || ',' || machine || ',' ||
  82.   --                  program || ',' || terminal || ',' || process, 1, 58)
  83.   --                  || ')]' clientinfo
  84.   --         from v$session where sid =
  85.   --           (select sid from v$mystat where rownum = 1);
  86.   --       grant select on dbms_mail$myclientinfo to <localmailacct>;
  87.   --         
  88.   --  4) Using the database link name chosen in step (2), create the 
  89.   --     following synonyms for use by this package:
  90.   --        create synonym mail_info     for email.s_sender_info@<mailnode>;
  91.   --        create synonym mail_header   for email.s_send_header@<mailnode>;
  92.   --        create synonym mail_instance for email.s_send_instance@<mailnode>;
  93.   --        create synonym mail_body     for email.s_send_body@<mailnode>;
  94.   --        create synonym mail_name     for email.s_user_name@<mailnode>;
  95.   --        create synonym mail_seq      for email.m_id_seq@<mailnode>;
  96.   --
  97.   --  5) Do a "select * from dual@<mailnode>;" to make sure the node is
  98.   --     reachable.
  99.   --
  100.   --  6) Run this script
  101.   --
  102.   --  If your account does not have the privileges to create the public 
  103.   --  synonym at the end of this script then connect as internal or 'sys'
  104.   --  to create the synonym.  If the public synonym is not created then 
  105.   --  the user must invoke the package as
  106.   --       <localmailacct>.dbms_mail.send(...)
  107.   --  rather than
  108.   --       dbms_mail.send(...)
  109.   --  where <localmailacct> is the <user> name chosen above.
  110.   --
  111.   --  If <mailnode> points to a V6 database then you cannot call this
  112.   --  procedure from a trigger since that requires distributed transactions.
  113.   --
  114.   --  The distributed and procedural extensions are required to use this
  115.   --  feature.
  116.  
  117.   ------------------------
  118.   --  EXAMPLE INSTALLATION
  119.   --
  120.   --  You need to substitute appropriate values wherever you see <>'s.
  121.   --
  122.   --  ***Do this for the mail database***
  123.   --  connect email/<password>
  124.   --  @ora_system:utlmail.sql
  125.   --  connect sys/chg_on_install
  126.   --  grant connect to sp_mailer identified by <mailpassword>;
  127.   --  <also make 'sp_mailer' a valid Oracle*Mail user>
  128.   --
  129.   --  ***Do this for each database from which you want to send mail***
  130.   --  connect <localmailacct>/<password>
  131.   --  create database link maildb connect to sp_mailer identified by
  132.   --    <mailpassword> using '<connect string>';
  133.   --  select * from dual@maildb;
  134.   --  create synonym mail_info     for email.s_sender_info@maildb;
  135.   --  create synonym mail_header   for email.s_send_header@maildb;
  136.   --  create synonym mail_instance for email.s_send_instance@maildb;
  137.   --  create synonym mail_body     for email.s_send_body@maildb;
  138.   --  create synonym mail_name     for email.s_user_name@maildb;
  139.   --  create synonym mail_seq      for email.m_id_seq@maildb;
  140.   --  connect sys/chg_on_install
  141.   --  create or replace view dbms_mail$myclientinfo as
  142.   --    select ' [SENDER=(' ||
  143.   --      substr(osuser || ',' || user || ',' || machine || ',' ||
  144.   --             program || ',' || terminal || ',' || process, 1, 58)
  145.   --             || ')]' clientinfo
  146.   --    from v$session where sid =
  147.   --      (select sid from v$mystat where rownum = 1);
  148.   --  grant select on dbms_mail$myclientinfo to <localmailacct>;
  149.   --  connect <localmailacct>/<password>
  150.   --  @ora_system:dbmsmail.sql
  151.   --  execute dbms_mail.send('test-from', '<to-string>', 'cc-str', 'bcc-str', 
  152.   --    'test subject', '', 'test body');
  153.   --  commit
  154.   --  ***<to-string> should now receive the mail!
  155.  
  156.   ---------------------------
  157.   --  PROCEDURES AND FUNCTIONS
  158.   --
  159.   procedure send(from_str in varchar2, 
  160.                  to_str in varchar2, 
  161.                  cc in varchar2,
  162.                  bcc in varchar2,
  163.                  subject in varchar2, 
  164.                  reply_to in varchar2, 
  165.                  body in varchar2);
  166.   --  The send procedure sends and Oracle*Mail message to the specified
  167.   --    recipients.  The message is actually sent when the transaction
  168.   --    in which this call is made commits.  Consult the ORA*MAIL product
  169.   --    form information on size limits for the following arguments.
  170.   --  Input parameters:
  171.   --    from_str
  172.   --      This is the alternate name for the sender of this message.  Must
  173.   --      be <= 10 bytes long.  May be null.  Information about the client
  174.   --      process is also included as part of the sender information.
  175.   --    to_str
  176.   --      A comma or space separated list of Oracle*Mail users to send this
  177.   --      message to.
  178.   --    cc
  179.   --      A comma or space separated list of Oracle*Mail users to copy.
  180.   --    bcc
  181.   --      A comma or space separated list of Oracle*Mail users to blind copy.
  182.   --    subject
  183.   --      The subject heading for this message.
  184.   --    reply_to
  185.   --      The reply-to line for this message.
  186.   --    body
  187.   --      The message body, up to 2000 bytes.
  188.   --  Errors raised:
  189.   --    -20000, ORU-10014: user <username> does not have an Oracle*Mail
  190.   --        account on the mail node.
  191.   --      Cause: The user named in the 'maildb' database link must have
  192.   --        been given an Oracle*Mail account on the mail database.  The 
  193.   --        account need have no privileges other than 'connect'.
  194.   --
  195.  
  196. end;
  197. /
  198. create or replace package body dbms_mail as
  199.   user_id        number;
  200.   user_node       number;
  201.   msg_node       number;
  202.   sender_name       varchar(81);
  203.   name_at_mailnode varchar2(30);
  204.   client_id        varchar2(70);
  205.  
  206.   procedure send(from_str varchar2, to_str varchar2, cc varchar2, bcc varchar2,
  207.       subject varchar2, reply_to varchar2, body varchar2) is
  208.     order_no    number;
  209.     pos         number;
  210.     bsize       number;
  211.     len         number;
  212.     smallbody   varchar2(240);
  213.     f_str    varchar2(80) := from_str;
  214.   begin
  215.     -- Accurately (as possible) identify the real user based on the actual
  216.     -- client process.  It is easy for dba's to create database accounts
  217.     -- with arbitrary names so don't rely on those.
  218.     f_str := substr(f_str,1,10) || client_id;
  219.  
  220.     begin
  221.       if user_id IS NULL then
  222.         select sender_name, msg_node, user_id, user_node
  223.           into sender_name, msg_node, user_id, user_node
  224.           from mail_info;
  225.       end if;
  226.     exception when no_data_found then
  227.       raise_application_error(-20000, 'ORU-10014: user "' || name_at_mailnode
  228.          || '" does not have an Oracle*Mail account on the mail node');
  229.  
  230.     end;
  231.  
  232.     insert into mail_header (msg_id, msg_node, type, part_type, 
  233.         hdr_flags, sender_id, sender_node, sender_date, reply_to, to_str, 
  234.         cc_str, bcc_str, subject, from_str, sender_name, deferred, 
  235.         inclusion_id, inclusion_node)
  236.       values (mail_seq.nextval, msg_node, 1, 0, 0, user_id, user_node, sysdate,
  237.         reply_to, to_str, cc, bcc, subject, f_str, sender_name, 'N', 0, 0);
  238.  
  239.     insert into mail_instance (msg_id, msg_node, node_id, msg_owner,
  240.       folder_id, retention_date, unread_flag, flags)
  241.     values (mail_seq.currval, msg_node, user_node, user_id, 2, sysdate,
  242.       'Y', 0);
  243.  
  244.     order_no := 1;
  245.     pos := 1;
  246.     bsize := length(body);
  247.     while bsize > 0 loop
  248.       if bsize > 240 then 
  249.         len := 240;
  250.       else
  251.         len := bsize;
  252.       end if;
  253.       -- compute substr here because the entire query below is sent
  254.       -- to the remote site, and V6 can't handle longs (body is a long)
  255.       smallbody := substr(body,pos,len);
  256.       insert into mail_body (msg_id, msg_node, part, order_no, msg_line)
  257.         values (mail_seq.currval, msg_node, 0, order_no, smallbody);
  258.       order_no := order_no + 1;
  259.       pos := pos + len;
  260.       bsize := bsize - len;
  261.     end loop;
  262.   end;
  263.  
  264. begin
  265.   -- for error messages
  266.   select user_name into name_at_mailnode from mail_name;
  267.  
  268.   -- get client info to more accurately identify who is sending this email
  269.   select clientinfo into client_id
  270.     from sys.dbms_mail$myclientinfo;
  271. end;
  272. /
  273. drop public synonym dbms_mail
  274. /
  275. create public synonym dbms_mail for dbms_mail
  276. /
  277.